home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
CC_C
/
0294.ZIP
/
SHELL2.ARC
/
MORE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1985-08-08
|
5KB
|
288 lines
#include "gen.h"
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dos.h>
/*
* more: a Unix(tm) like more command for MS-DOS
*
* by Douglas Orr
* Textset Inc.
* Ann Arbor, Michigan
*
* Copyright (c) 1985 Textset. All rights reserved.
*
* This program may be freely distributed, but not sold for profit.
*
*/
/*
* To compile: msc -Ze more.c
*
* Code in chin must be changed if you go to a large memory model.
*/
Local char esc = '\033';
Local char ctl_z = '\032';
Local FILE * con = NULL;
main( argc, argv )
int argc;
char * argv[];
{
int fd;
struct stat statb;
while( --argc )
{
if( (*++argv)[0] == '-' )
switch( (*argv)[1] )
{
default:
fprintf( stderr, "invalid argument %s\n", *argv );
exit(1);
}
else
break;
}
if( argc == 0 )
{
more( NULL, fileno(stdin), 0L);
exit( 0 );
}
else
while( argc-- )
{
if( (fd = open( *argv, O_RDONLY+O_BINARY )) < 0 )
fprintf( stderr, "couldn't open %s\n", *argv );
else
{
statb.st_size = 0; /* just in case fstat fails */
fstat( fd, &statb );
more( *argv, fd, statb.st_size );
close( fd );
}
argv++;
if( argc )
{
printf( "%c[7m Next file: %s %c[0m", esc, *argv, esc );
chin();
printf( "\r%c[K", esc );
}
}
}
Local char buffer[BUFSIZ];
Local int bufp = 0;
Local long pos = 0;
Local int cnt = 0;
Local int eof;
initfile()
{
bufp = pos = cnt = 0;
eof = False;
}
long
getline( fd, line, linesize )
int fd;
char * line;
int linesize;
{
int linep;
bool eol;
if( eof )
return( -1 );
for( linep=0; linep < linesize; )
{
if( bufp >= cnt )
{
pos += cnt;
bufp = 0;
if( (cnt = read( fd, buffer, sizeof buffer )) == 0 )
{
if( linep != 0 )
{
eof = True;
break;
}
return( -1 );
}
}
/* newline signals eol */
if( buffer[bufp] == '\n' )
{
bufp++;
break;
}
else
if( buffer[bufp] == ctl_z )
{
eof = True;
break;
}
else
{
/* ignore crs */
if( buffer[bufp] != '\r' )
line[linep++] = buffer[bufp];
bufp++;
}
}
line[linep] = '\0';
return( pos + bufp );
}
more(fname, fd, size)
char * fname;
int fd;
long size;
{
int cnt;
char buf[80];
long pos;
long lineno = 0;
initfile();
if( fname )
{
printf( "%c[1m More: File <%s> %c[0m\n", esc, fname, esc );
cnt = 1;
}
else
cnt = 0;
while( (pos = getline( fd, buf, sizeof(buf)-1 )) >= 0 )
{
printf( "%s\n", buf );
lineno++;
if( (++cnt % 24) == 0 )
{
bool done;
if( size )
printf( "%c[7m -More(%ld%%)- %c[0m", esc,
((pos*100)/size), esc );
else
printf( "%c[7m -More- %c[0m", esc, esc );
for( done=False; !done; )
{
done = True;
switch( chin() )
{
case ' ':
cnt = 0;
break;
case '\r':
case '\n':
cnt--;
break;
case 'q':
printf( "\n" );
exit(0);
case 'v':
sprintf( buf, "v %s", fname );
system( buf );
cnt--;
break;
case ':':
switch( chin() )
{
case 'n':
printf( "\r%c[K", esc );
return;
}
default:
done = False;
break;
}
}
printf( "\r%c[K", esc );
}
}
}
/*
* !! Today's mystery: I have tried every way that I can think of
* to open con: in binary mode, using uSoft routines, and I just
* can't get it. I open with the right flags, using open or fopen,
* and the file descriptor comes up as non-binary when polled via
* ioctl. Even "setmode" doesn't work. What gives?
*
* the result is what follows:
*
*/
chin()
{
Local int confd = -1;
union REGS regs;
char far * buf; /* need -Ze to compile */
char buffer[1];
if( confd < 0 )
{
if( (confd = open("con", O_RDONLY)) < 0 )
{
fprintf( stderr, "couldn't open con:\n" );
exit(1);
}
/* get the current ioctl bits for con: */
regs.h.ah = 0x44;
regs.h.al = 0;
regs.x.bx = confd;
intdos( ®s, ®s );
/* flip on binary mode */
regs.h.ah = 0x44;
regs.h.al = 1;
regs.x.bx = confd;
regs.x.dx |= 0x20;
regs.x.dx &= ~(0x8010);
intdos( ®s, ®s );
}
/* read seems to be a bit problematical, also */
buf = buffer;
regs.h.ah = 0x3f;
regs.x.bx = confd;
/* !! small model - ds is the current ds */
regs.x.dx = FP_OFF(buf);
regs.x.cx = 1;
intdos( ®s, ®s );
return( buf[0] );
}